"""qq登陆辅助类工具 ,拼接url"""
import logging
import json
from itsdangerous import TimedJSONWebSignatureSerializer as TJWSSerializer, BadData
from urllib.parse import urlencode, parse_qs
from urllib.request import urlopen

from django.conf import settings  # 相当于导入dev

from oauth import constants
from oauth.exceptions import QQAPIError

logger = logging.getLogger('django')

class OAuthQQ(object):
    """qq验证辅助类工具"""
    # 用户传入参数, 没有传入有默认值
    def __init__(self, client_id=None, client_secret=None, redirect_uri=None, state=None):
        self.client_id = client_id or settings.QQ_CLIENT_ID
        self.client_secret = client_secret or settings.QQ_CLIENT_SECRET
        self.redirect_uri = redirect_uri or settings.QQ_REDIRECT_URI
        self.state = state or settings.QQ_STATE  # 用于保存登录成功后的跳转页面路径


    def get_qq_login_url(self):
        """
        获取qq登录的网址
        :return: url网址
        """
        params = {
            'response_type': 'code',
            'client_id': self.client_id,
            'redirect_uri': self.redirect_uri,
            'state': self.state,
            'scope': 'get_user_info',
        }

        # 利用urlencode工具拼接网址
        url = 'https://graph.qq.com/oauth2.0/authorize?' + urlencode(params)
        return url


    def get_access_token(self, code):
        """
        获取access_token
        :param code: qq提供的code
        :return: access_token
        """
        params = {
            'grant_type': 'authorization_code',
            'client_id': self.client_id,
            'client_secret': self.client_secret,
            'code': code,
            'redirect_uri': self.redirect_uri
        }

        url = 'https://graph.qq.com/oauth2.0/token?' + urlencode(params)
        try:
            response = urlopen(url)  # 发送请求url,获取返回值

            response_data = response.read().decode()  # 转化成字符串

            # 将qs查询字符串格式数据转换为python的字典
            data = parse_qs(response_data)  # 转化成字典
        except Exception as e:
            logging.error('获取access_token错误:%s' % e)
            raise QQAPIError
        else:
            access_token = data.get('access_token', None)
            if not access_token:
                logger.error('code=%s msg=%s' % (data.get('code'), data.get('msg')))
                raise QQAPIError
            # 返回access_token
            return access_token[0]  # 是个列表,需要切片


    def get_openid(self, access_token):
        """
        #  根据access_token获取openid
        :param access_token:
        :return:
        """
        # 只有一个参数,手动拼接,向qq发送请求

        url = 'https://graph.qq.com/oauth2.0/me?access_token=' + access_token
        try:
            response = urlopen(url)

            response_data = response.read().decode()
            # 返回的数据 callback( {"client_id":"YOUR_APPID","openid":"YOUR_OPENID"} )\n;
            # 将返回的字符串切片,转换成字典
            data = json.loads(response_data[10:-4])
        except Exception as e:
            # data = parse_qs(response_data)
            # logger.error('code=%s msg=%s' % (data.get('code'), data.get('msg')))
            logging.error('获取openid错误:%s' % e)
            raise QQAPIError
        else:
            openid = data.get('openid', None)
        return openid


    def generate_save_user_token(self, openid):
        # 接受openid, 转换成自己的token进行用户第一次绑定使用
        serializer = TJWSSerializer(settings.SECRET_KEY, expires_in=constants.SAVE_QQ_USER_TOKEN_EXPIRES)
        token = serializer.dumps({'openid': openid})
        return token.decode()

    @staticmethod
    def check_bind_user_access_token(access_token):
        serializer = TJWSSerializer(settings.SECRET_KEY, expires_in=constants.SAVE_QQ_USER_TOKEN_EXPIRES)
        try:
            data = serializer.loads(access_token)
        except BadData:
            return None
        else:
            return data['openid']





